package com.example.demo;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import com.netflix.hystrix.exception.HystrixTimeoutException;

/**
 * 
 * 由代码可知： Dalston及更低版本通过实现 ZuulFallbackProvider 接口，从而实现回退； Edgware及更高版本通过实现
 * FallbackProvider 接口，从而实现回退。 在Edgware中：
 * FallbackProvider是ZuulFallbackProvider的子接口。 ZuulFallbackProvider已经被标注
 * Deprecated ，很可能在未来的版本中被删除。 FallbackProvider接口比ZuulFallbackProvider多了一个
 * ClientHttpResponsefallbackResponse(Throwablecause); 方法，使用该方法，可获得造成回退的原因。
 * 
 * @author Administrator
 *
 */
@Component
public class MyFallbackProvider implements FallbackProvider {
	@Override
	public String getRoute() {
		return "*";
	}

	@Override
	public ClientHttpResponse fallbackResponse() {
		return this.response(HttpStatus.INTERNAL_SERVER_ERROR);

	}

	@Override
	public ClientHttpResponse fallbackResponse(Throwable cause) {
		if (cause instanceof HystrixTimeoutException) {
			return response(HttpStatus.GATEWAY_TIMEOUT);
		} else {
			return this.fallbackResponse();
		}
	}

	private ClientHttpResponse response(final HttpStatus status) {
		return new ClientHttpResponse() {

			@Override
			public HttpHeaders getHeaders() {
				HttpHeaders headers = new HttpHeaders();
				MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8"));
				headers.setContentType(mt);
				return headers;
			}

			@Override
			public InputStream getBody() throws IOException {
				return new ByteArrayInputStream("服务不可用，请稍后再试。".getBytes());
			}

			@Override
			public String getStatusText() throws IOException {
				return status.getReasonPhrase();
			}

			@Override
			public HttpStatus getStatusCode() throws IOException {
				return status;
			}

			@Override
			public int getRawStatusCode() throws IOException {
				return status.value();
			}

			@Override
			public void close() {

			}
		};
	}
}